import React, {
  forwardRef,
  useMemo,
  useEffect,
  useImperativeHandle,
} from "react";
import { createPortal } from "react-dom";
import { getAttach } from "@/utils";
import { message } from "antd";

/**
 * Portal组件属性定义
 */
export interface PortalProps {
  /**
   * 指定挂载的DOM节点，可以是DOM元素或CSS选择器
   * @default document.body
   */
  attach?: HTMLElement | string;
  /**
   * 需要挂载到指定节点的子元素
   */
  children?: React.ReactNode;
}

/**
 * Portal组件，将子元素渲染到指定的DOM节点中，而不是组件当前所在的DOM树结构中
 * @param props - 组件属性
 * @param ref - 转发的ref引用，指向承载子元素的DOM容器
 * @returns 使用ReactDOM.createPortal创建的传送门
 */
const Portal = forwardRef((props: PortalProps, ref) => {
  const { attach = document.body, children } = props;
  const clear = () => {
    message.error("你这是错误的");
  };
  // 创建一个空的div元素作为容器
  const container = useMemo(() => {
    const el = document.createElement("div");
    return el;
  }, []);

  // 将container添加到指定的挂载点，并在组件卸载时移除
  useEffect(() => {
    const target = getAttach(attach);
    target?.appendChild(container);
    return () => {
      target?.removeChild(container);
    };
  }, [container, attach]);

  // 将container通过ref暴露给父组件
  useImperativeHandle(ref, () => ({
    container,
    clear,
  }));

  // 使用ReactDOM.createPortal将children渲染到container中
  return createPortal(children, container);
});

export default Portal;
